/****************************************************************************
* copyright            : (C) 2009 William Viana Soares <vianasw@gmail.com>  *
*****************************************************************************/

/****************************************************************************
*                                                                           *
*   This program is free software; you can redistribute it and/or modify    *
*   it under the terms of the GNU General Public License as published by    *
*   the Free Software Foundation; either version 2 of the License, or       *
*   (at your option) any later version.                                     *
*                                                                           *
*****************************************************************************/

#ifndef SCENE_H
#define SCENE_H

#include "point.h"
#include "querymaker.h"

#include <map>
#include <string>
#include <vector>

namespace ConciseQSR
{
    
using namespace std;

/**
 * @class Scene
 * @short A class that holds qualitative spatial information about a set of points and makes possible to infer new information.
 */
class Scene
{
public:
    static const int MAX_TRIES = 1;    

    Scene( QueryMaker *qm = 0 ): m_qm( qm ){};
    
    /**
    * @param points the initial vector of points to build the set of relations between each other
    */
    Scene( vector< Point > &points, QueryMaker *qm = 0 );
    ~Scene();
    
    /**
    * Adds a new point and a reference system to the scene and qualify the relation between the point and the reference
    * @param point the new point to add to the scene
    * @param ref the reference system to qualify with the point
    */
    void addPoint( Point point, Reference ref );
    
    /**
    * Adds a new point and a reference system to the scene and qualify the relation between the point and the reference
    * @param point the new point to add to the scene
    * @param refPointA the first point in the reference system
    * @param refPointB the second point in the reference system
    */
    void addPoint( Point point, Point refPointA, Point refPointB );
    
    vector< string > getRelations( Point &point, Reference &reference );
    
    /**
    * Sets the query maker which deals with SparQ directly
    * @param qm the object of the class that communicates with SparQ 
    */
    void setQueryMaker( QueryMaker *qm );
    
    /**
    * @return the QueryMaker object associated to the class
    */
    const QueryMaker* queryMaker() const;
    
    friend ostream& operator<<( ostream &os, const Scene &s );

    
private:
    /**
    * Algebraic closure
    */
    void aClosure( Point &p, Reference &r );
    
    /** 
    * Qualify points using SparQ
    */
    void qualifyPoints();
    
    string m_constraints; //internal representation of constraints received by SparQ
    
    vector< Point > m_ordPoints; // points ordered by insertion
    map< string, Point > m_points; // ( label, point )
    QueryMaker *m_qm;     
    int m_queryTries;
};
} // namespace ConciseQSR
#endif